import Pyro4
import time
import thread


def dump(obj):
  newobj=obj
  if '__dict__' in dir(obj):
    newobj=obj.__dict__
    if ' object at ' in str(obj) and not newobj.has_key('__type__'):
      newobj['__type__']=str(obj)
    for attr in newobj:
      newobj[attr]=dump(newobj[attr])
  return newobj
class BillType(object):
    def __init__(self):
        pass
def format_duration(duration):
    detik = duration % 60
    menit= duration / 60
    jam    = 0
    hari   = 0
    minggu = 0
    if menit >= 60 :
        jam = menit / 60
        menit = menit % 60
        if jam >= 24 :
            hari = jam / 24
            jam  = jam % 24
            if hari >= 7 :
                minggu = hari / 7
                hari = hari % 7
    output = ""
    if minggu > 0 :
        output += "{0} Minggu ".format(minggu)
    if hari > 0 :
        output += "{0} Hari ".format(hari)
    if jam > 0 :
        output += "{0} Jam ".format(jam)
    if menit > 0:
        output += "{0} Menit ".format(menit)
    if detik > 0 :
        output += "{0} Detik ".format(detik)
    return " %s - ( %d detik )." % (output,duration)

class BillingData(object):
    def __init__(self,id):
        self.id = id
        # Store the initial server time
        self.server_time = None
        # Store station first login time
        self.start_time = None
        # Store station bill type
        self.bill_type  = None
        # Store increment server duration of given station added inside server
        self.server_duration = 0
        # Store increment client duration sent by client via network
        self.client_duration = 0
        # Store the state that billing station has already started
        self.active = False
        # Store the calculated cost beside of server duration
        self.server_tcost = 0
        # Store the calculated cost beside of client duration
        self.client_tcost = 0
        # Store the additional cost
        self.acost = []
        # Flags to initiate bill logout at server duration
        self.stop_at_server_duration = 0
        # Flags to initiate bill logout ad client duration
        self.stop_at_client_duration = 0
        # Cost persecond in Rupiahs
        self.cost_per_second = 0.834
        # Total cost server
        self.server_total_cost = 0
        #Client total cost
        self.client_total_cost = 0

    def to_string(self):
        return """
        CLIENT ID       : %s
        SERVER TIME     : %s
        START TIME      : %s
        BILL TYPE       : %s
        SERVER DURATION : %s
        CLIENT DURATION : %s
        ACTIVE          : %s
        SERVER TCOST    : %s
        CLIENT TCOST    : %s
        ADDITIONAL COST : %s
        STOP AT SRV DUR : %s
        STOP AT CLN DUR : %s
        COST PER SEC    : %s
        SRV TOTAL COST  : %s 
        CLN TOTAL COST  : %s """ % (  self.id,
                                time.ctime(self.server_time),
                                time.ctime(self.start_time),
                                self.bill_type,
                                format_duration(self.server_duration),
                                format_duration(self.client_duration),
                                self.active,
                                "Rp.{:6,d},_".format(self.server_tcost) + ("%d" % self.server_tcost),
                                self.client_tcost,
                                "|".join(self.acost),
                                format_duration( self.stop_at_server_duration ),
                                format_duration( self.stop_at_client_duration ),
                                self.cost_per_second,
                                "Rp.{:6,d},_".format(self.server_total_cost),
                                self.client_total_cost  )


def create_default_billing_data(id):
    print "create_default_billing_data (%s) " % id
    billdata = BillingData(id)
    current_tstamp = time.time()
    billdata.server_time = current_tstamp
    billdata.start_time = current_tstamp
    billdata.bill_type = 'Personal'
    billdata.active = True
    return billdata


def update_billing_data(client_id,delay):
    global bill_data
    billdata = bill_data[client_id] 
    while billdata.active:
        time.sleep(delay)
        print "update_billing_data (%s) " % client_id
        billdata.server_time = time.time()
        billdata.server_duration += delay
        billdata.server_tcost = int(billdata.server_duration * billdata.cost_per_second)
        billdata.server_total_cost = billdata.server_tcost
        for acost in billdata.acost :
            billdata.server_total_cost += acost
        
    print "thread exit %s" % client_id
    del bill_data[client_id]




bill_data = {}

class BillServer(object):
    def __init__(self):
        global bill_data
        self.bill_data = bill_data
        pass
    #self.test()
    def test(self):
        client_id = 'Ok'
        try:
            thread.start_new_thread( update_billing_data, (client_id,1) )
        except:
            print "Error: unable to start update_billing_data (%s)" % client_id
    def login(self,client_id):
        global bill_data
        billdata = False
        if client_id in bill_data :
            return True
        else:
            billdata = create_default_billing_data(client_id)
            bill_data[client_id] = billdata
            try:
               thread.start_new_thread( update_billing_data, (client_id,3) )
            except:
               print "Error: unable to start update_billing_data (%s)" % client_id 
               print dump(bill_data)
        
        return False

    def logout(self,client_id):
        global bill_data
        if client_id in bill_data:
            bill_data[client_id].active = False
            
        
    def get_bill_data(self,client_id):
        return self.bill_data[client_id].to_string()

        


def main():
   billserver=BillServer()
   Pyro4.Daemon.serveSimple(
      {
	    billserver: "billserver.damarnet"
	  },
	  ns=False,host='127.0.0.1',port=2012)


if __name__=="__main__":
  main()